import PageResponse from '@/core/framework/types/model/response/PageResponse'
import debounceUtils from '@/core/utils/debounceUtils'
import authManager from '@/core/auth/manager/authManager'
import promiseUtils from '@/core/utils/promiseUtils'
import BaseAdminServerApi from '@/core/framework/serverapi/BaseAdminServerApi'

export type BaseAdminServiceProps<Id, Response> = {
	adminServerApi: BaseAdminServerApi<Id, Response>
}

class BaseAdminService<Id, Response> {
	private adminServerApi: BaseAdminServerApi<Id, Response>

	private getByIdsWithDebounceFnInternal: (id: Id) => Promise<Response[]> = debounceUtils.define<Id, Response[]>(
		(ids: Id[]): Promise<Response[]> => {
			const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
			const responsePromise = this.adminServerApi.getByIds(userAccessToken, ids)
			return promiseUtils.ofResponse(responsePromise).check()
		},
	)

	constructor(params: BaseAdminServiceProps<Id, Response>) {
		this.adminServerApi = params.adminServerApi
	}

	getByIdsWithDebounce = (id: Id): Promise<Response[]> => {
		return this.getByIdsWithDebounceFnInternal(id)
	}

	getByIds = (ids: Id[]): Promise<Response[]> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.getByIds(userAccessToken, ids)
		return promiseUtils.ofResponse(responsePromise).check()
	}

	getById = (id: Id): Promise<Response> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.getById(userAccessToken, id)
		return promiseUtils.ofResponse(responsePromise).check()
	}

	search = (query?: string, page?: number, size?: number, sort?: string[]): Promise<PageResponse<Response>> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.search(userAccessToken, query, page, size, sort)
		return promiseUtils.ofResponse(responsePromise).check()
	}

	add = (data: Response): Promise<Response> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.add(userAccessToken, data)
		return promiseUtils.ofResponse(responsePromise).check()
	}

	modifyNotNullField = (data: Response): Promise<Response> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.modifyNotNullField(userAccessToken, data)
		return promiseUtils.ofResponse(responsePromise).check()
	}

	removeLogic = (ids: Id[]): Promise<boolean> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.removeLogic(userAccessToken, ids)
		return promiseUtils.ofResponse(responsePromise).check()
	}

	remove = (ids: Id[]): Promise<boolean> => {
		const userAccessToken = authManager.getAndCheckUserTokenInfo().accessToken
		const responsePromise = this.adminServerApi.removeLogic(userAccessToken, ids)
		return promiseUtils.ofResponse(responsePromise).check()
	}
}

export default BaseAdminService
